/*
 * 教材中的示例程序之完整版.
 * 书名：《编译原理基础》
 * 版次：第三版
 * 作者：王献青，张立勇，张淑平，刘坚
 * 出版社：西安电子科技大学出版社
 * 程序完成时间：2025.03
 */

//
// 文件内容：直接编码的识别函数2
//

#include "lexer.h"

//直接编码的识别函数2: 基于goto的实现
//::  教材程序清单2.3
TokenKind recognize_word_direct_coded_2()
{
    char c = *forward;               // 读取第一个字符
    if ( IS_EOF (c) ) return EOFS;   // 通知调用者：输入已分析结束

    goto S0; // 若初态0的程序块没有排在最前面，则这个goto是必须的

S0: // 初态0的程序块排列在最前面
    switch ( c ) {
        case '<': goto S1;  // 转向状态1
        case '!': goto S3;  // 转向状态3
        case '=': goto S5;  // 转向状态5
        case '>': goto S7;  // 转向状态7
        default:
            if ( IS_LETTER (c) ) goto S10;       // 转向状态10
            else if ( IS_DIGIT (c) ) goto S12;   // 转向状态12
            else return ERROR;  // 第1个字符无效
    }

S1: // 状态1的程序块
    c = *(++forward);               // 读取下一字符
    if ( c == '=' ) goto S2;        // 转向状态2
    else { --forward; return LT; }  // 退回其他字符，返回LT
S2: return LE;

S3: // 状态3的程序块
    c = *(++forward);               // 读取下一字符
    if ( c == '=' ) goto S4;        // 转向状态4
    else { --forward; return NOT; } // 退回其他字符，返回NOT
S4: return NE;

S5: // 状态5的程序块
    c = *(++forward);               // 读取下一字符
    if ( c == '=' ) goto S6;        // 转向状态6
    else { --forward; return ASSIGN; } // 退回其他字符，返回ASSIGN
S6: return EQ;

S7: // 状态7的程序块
    c = *(++forward);               // 读取下一字符
    if ( c == '=' ) goto S8;        // 转向状态8
    else { --forward; return GT; }  // 退回其他字符，返回GT
S8: return GE;

S10:
    c = *(++forward);
    if ( IS_LETTER (c) ) goto S10;  // 转向状态10，对应转换图中的环
    else if ( IS_DIGIT (c) ) goto S10;
    else { --forward; return ID; }  // 退回其他字符，返回ID

S12:
    c = *(++forward);
    if ( c == '.' ) goto S13;
    else if ( c == 'E'  ) goto S15;
    else if ( IS_DIGIT (c) ) goto S12; // 转向状态12，对应转换图中的环
    else { --forward; return INT; } // 退回其他字符，返回INT

S13:
    c = *(++forward);
    if ( IS_DIGIT (c) ) goto S14;
    else {  // 小数点后面不是数字的处理
        // 这里的处理仅为演示：有些应用中，需要状态回退到
        //   最近一次经历的终态
        --forward; --forward;
        return INT;   // 接受整数部分
    }

S14:
    c = *(++forward);
    if ( IS_DIGIT (c) ) goto S14;
    else if ( c == 'E'  ) goto S15;
    else { --forward; return REAL; } // 退回其他字符，返回REAL

S15:
    c = *(++forward);
    if ( c == '+' || c == '-'  ) goto S16;
    else if ( IS_DIGIT (c) ) goto S17;
    else { return ERROR; } // 指数部分的E后面的字符无效，直接返回错误

S16:
    c = *(++forward);
    if ( IS_DIGIT (c) ) goto S17;
    else { return ERROR; } // 指数部分的正负号后面的字符无效，直接返回错误

S17:
    c = *(++forward);
    if ( IS_DIGIT (c) ) goto S17;
    else { --forward; return REAL; } // 退回其他字符，返回REAL

}
